1 00:00:01,460 --> 00:00:05,300 In this lecture, we're going to start finally creating stuff in Roblox. 2 00:00:05,300 --> 00:00:10,010 Specifically in this video, we're going to learn about the tool instance and how we can use it to create 3 00:00:10,010 --> 00:00:11,390 custom tools in our game. 4 00:00:12,150 --> 00:00:17,040 I've created this simple donut model here, and you can grab this model yourself by going to the attached 5 00:00:17,040 --> 00:00:20,010 link in this lecture and adding the model to your inventory. 6 00:00:20,680 --> 00:00:23,020 Once you do that, you can go to the View tab. 7 00:00:24,400 --> 00:00:28,210 Open up the toolbox and go to the inventory tab. 8 00:00:29,020 --> 00:00:31,750 And grab the model from the my model section. 9 00:00:33,800 --> 00:00:39,650 Now we can create a new tool instance and place it in the workspace by pressing this plus button here 10 00:00:39,770 --> 00:00:41,390 and I'll search for a new tool. 11 00:00:43,510 --> 00:00:47,440 And then I can take my donut model here and make it a child of the tool. 12 00:00:48,320 --> 00:00:53,810 The next thing I want to do is remove this model so the tool has direct access to the parts that make 13 00:00:53,810 --> 00:00:54,290 it up. 14 00:00:54,980 --> 00:00:58,160 I can un group these objects by using the combined control. 15 00:00:58,160 --> 00:00:58,940 And you. 16 00:00:59,970 --> 00:01:04,680 The next thing I have to do is rename one of these parts to handle because our tool requires a part 17 00:01:04,680 --> 00:01:06,600 to be identified as a handle. 18 00:01:06,600 --> 00:01:09,330 So the player model knows exactly where to hold the tool at. 19 00:01:09,990 --> 00:01:13,110 So I'll just rename the body of my donut to handle. 20 00:01:13,560 --> 00:01:16,400 We also have to make sure that our tool is unanchored. 21 00:01:16,410 --> 00:01:21,510 Otherwise, if it's anchored, we would not be able to move the character because our hand gets welded 22 00:01:21,510 --> 00:01:23,100 to the donut that's stuck. 23 00:01:24,500 --> 00:01:29,630 One more thing to mention is that since we have two separate parts in our tools that are both unanchored, 24 00:01:29,630 --> 00:01:34,100 we have to weld the extra parts like the icing here to the handle. 25 00:01:34,250 --> 00:01:38,120 That way all the separate parts act as one unit, as one part. 26 00:01:38,570 --> 00:01:42,650 To do this, I can add a weld constraint and make it a child of my icing. 27 00:01:42,740 --> 00:01:45,540 But it doesn't really matter where you parent the weld constraint. 28 00:01:45,560 --> 00:01:49,190 Just know that the first part to the well constraint has to be my icing. 29 00:01:49,670 --> 00:01:53,450 And then the second part is going to be the part I want to weld the icing to. 30 00:01:53,450 --> 00:01:55,250 And in this case, that's the handle. 31 00:01:55,760 --> 00:01:59,810 Now I'll be able to properly hold this doughnut without getting my character stuck. 32 00:02:00,590 --> 00:02:03,020 So we have the shell of our tool created. 33 00:02:03,050 --> 00:02:07,490 Now, how exactly do we script our tool and make it to where I can, I don't know, heal us when we 34 00:02:07,490 --> 00:02:08,000 eat it? 35 00:02:08,570 --> 00:02:12,500 Well, we can create a new local script and make it a child of the tool. 36 00:02:14,560 --> 00:02:17,680 Local scripts specifically run on the client and they do this. 37 00:02:17,680 --> 00:02:22,840 So we're able to know when our player activates our tools, clicks, moves around, presses a certain 38 00:02:22,840 --> 00:02:23,920 key, and so on. 39 00:02:23,920 --> 00:02:28,810 Only local scripts see this and not the server scripts because the server doesn't know exactly what 40 00:02:28,810 --> 00:02:32,380 keys a player is pressing because it's not running on their computer. 41 00:02:33,350 --> 00:02:39,740 So in my local script, I kind of wanted to detect when my player clicks so that way they'll eat the 42 00:02:39,770 --> 00:02:42,580 donut and then I'll heal them with a little bit of health. 43 00:02:44,510 --> 00:02:46,760 I got a first get access to that player. 44 00:02:46,760 --> 00:02:54,020 So to do that, I'm going to create a reference to the player service, which holds all the players 45 00:02:54,020 --> 00:02:54,650 in my game. 46 00:02:54,650 --> 00:03:00,140 This service right here, any time a new client gets added, their player gets put into this service. 47 00:03:01,000 --> 00:03:04,270 And then to get the local player that's executing the script. 48 00:03:05,850 --> 00:03:07,210 I'll create another variable. 49 00:03:07,230 --> 00:03:15,200 I will index the player service and use the local player key value pair to grab the local player. 50 00:03:15,210 --> 00:03:18,780 This will always return the player that is executing the script. 51 00:03:19,170 --> 00:03:23,370 So now that I have access to this player, the other thing I want to access is the tool itself. 52 00:03:23,520 --> 00:03:30,270 So I'll create a variable, call it tool, and then I'll type in the script keyword and the script keyword 53 00:03:30,270 --> 00:03:33,540 refers to this script itself, this script instance. 54 00:03:33,930 --> 00:03:35,580 And then I could do Dot Parent. 55 00:03:35,580 --> 00:03:41,580 And what this does is that this references the parent of my script, which would be the tool, this 56 00:03:41,580 --> 00:03:42,600 tool instance. 57 00:03:43,620 --> 00:03:46,890 Now the tool instance has an event in it called activated. 58 00:03:47,040 --> 00:03:49,220 And this gets fired when a player clicks. 59 00:03:49,230 --> 00:03:50,820 So that's exactly what I want to happen. 60 00:03:50,820 --> 00:03:54,210 When my player clicks, I want them to eat the donut and heal a little bit. 61 00:03:54,630 --> 00:03:57,120 So I'll connect a lambda function to this event. 62 00:03:57,450 --> 00:04:03,300 And then what I could do is I could get my player index the player and get their character, which is 63 00:04:03,300 --> 00:04:04,500 their character model. 64 00:04:04,500 --> 00:04:08,550 And inside their character model they have something called a humanoid. 65 00:04:08,760 --> 00:04:14,640 And this humanoid holds all the properties like health, the players walk speed, all that kind of good 66 00:04:14,640 --> 00:04:17,640 stuff, basically the controller for the character. 67 00:04:17,970 --> 00:04:25,320 And it has a health property that I can access and maybe I want to heal my humanoid by five health so 68 00:04:25,320 --> 00:04:27,750 I can actually do plus equals five. 69 00:04:28,770 --> 00:04:31,980 Now to actually see my player get healed by my tool. 70 00:04:32,220 --> 00:04:35,310 I'm going to go on my game here and I'm going to create a new part. 71 00:04:38,420 --> 00:04:40,640 And this part is going to have a script in it. 72 00:04:42,180 --> 00:04:43,670 And I'll just make sure my part's anchored. 73 00:04:43,680 --> 00:04:44,400 Of course. 74 00:04:44,520 --> 00:04:50,370 And in the script, I'm just going to get a reference to the part by using the same script parent because 75 00:04:50,370 --> 00:04:52,470 this script is a child of the part. 76 00:04:53,830 --> 00:04:55,720 And then I'll access the touched event. 77 00:04:57,970 --> 00:04:59,470 And get the part that touched it. 78 00:04:59,740 --> 00:05:06,430 And I want to see if this part that is touching my part belongs to a character model that has a humanoid 79 00:05:06,430 --> 00:05:09,520 instance in it, which means that it's a player that I can damage. 80 00:05:10,810 --> 00:05:11,860 So I'll create a variable. 81 00:05:11,860 --> 00:05:13,000 I'll call it humanoid. 82 00:05:14,330 --> 00:05:17,000 And it's going to store the result of part parent. 83 00:05:18,240 --> 00:05:23,760 And I'm going to find the first child, which is a humanoid, belongs to the humanoid class. 84 00:05:23,760 --> 00:05:29,520 So what this means is that any ligament that touches my part like a leg, a foot, whatever, if the 85 00:05:29,520 --> 00:05:32,280 parent of it, which should be a character. 86 00:05:32,990 --> 00:05:36,260 And that character has a humanoid instance in it. 87 00:05:36,260 --> 00:05:38,150 That means it's a player so we can damage it. 88 00:05:40,800 --> 00:05:43,380 So create an if statement so if humanoid. 89 00:05:43,680 --> 00:05:51,090 So if this function returns an object doesn't return nil, then I'll damage the humanoid using the take 90 00:05:51,090 --> 00:05:54,360 damage function and I'll put a number in here like ten. 91 00:05:54,690 --> 00:05:57,810 So every time a player touches this part, they get damaged by ten. 92 00:05:59,720 --> 00:06:01,460 Now I'll be able to play my game. 93 00:06:05,310 --> 00:06:06,510 And then touch my part. 94 00:06:11,350 --> 00:06:12,760 Looks like it's not damaging me. 95 00:06:13,660 --> 00:06:15,700 Let's do a little debugging to find out why. 96 00:06:17,410 --> 00:06:19,570 Oh, other part. 97 00:06:20,500 --> 00:06:23,200 We're looking at the part that touched it, not the part itself. 98 00:06:23,230 --> 00:06:23,740 There we go. 99 00:06:23,740 --> 00:06:24,460 Fix that. 100 00:06:25,450 --> 00:06:28,210 That was an example of a logical error, by the way. 101 00:06:31,390 --> 00:06:34,570 Now, if I touch it, it killed me. 102 00:06:34,570 --> 00:06:36,100 That was a little too fast. 103 00:06:36,490 --> 00:06:38,020 Let me just touch it a little bit. 104 00:06:38,710 --> 00:06:39,320 There we go. 105 00:06:39,340 --> 00:06:40,480 I get damaged a lot. 106 00:06:40,690 --> 00:06:43,150 And now if I eat my donut, it should heal me. 107 00:06:45,390 --> 00:06:45,780 There we go. 108 00:06:45,780 --> 00:06:46,980 It's kind of healing me. 109 00:06:49,320 --> 00:06:51,180 This is very odd behavior. 110 00:06:52,520 --> 00:06:53,730 It's not actually healing me. 111 00:06:53,750 --> 00:06:55,070 Why isn't it healing me? 112 00:06:55,820 --> 00:06:58,900 The reason it's not healing me is because I'm running this heal. 113 00:06:58,910 --> 00:06:59,390 I'm change. 114 00:06:59,390 --> 00:07:04,160 I'm trying to alter the health of my humanoid from a local script and that's not going to replicate 115 00:07:04,160 --> 00:07:06,860 to the server and that's not going to replicate to other players. 116 00:07:07,160 --> 00:07:08,750 I need to do this. 117 00:07:08,750 --> 00:07:12,200 I need to perform this statement in a server script. 118 00:07:12,200 --> 00:07:15,110 The way it actually heals me and replicates to all the players. 119 00:07:15,350 --> 00:07:16,720 So how do I do that? 120 00:07:16,730 --> 00:07:18,650 Well, this is where remote events come in. 121 00:07:19,250 --> 00:07:25,370 So in my in my tool, I'll create another script and this is going to be a server script. 122 00:07:26,110 --> 00:07:29,230 And I'm just going to add an event to it, a remote event. 123 00:07:30,810 --> 00:07:31,650 And I'll just call. 124 00:07:31,650 --> 00:07:32,790 It clicked. 125 00:07:35,070 --> 00:07:39,930 In my server script, I'll create a reference to the event and I'll just name it event. 126 00:07:40,590 --> 00:07:44,010 So I'll do script Dot clicked. 127 00:07:44,940 --> 00:07:50,250 Again, script is referring to the script, and since the script has a child name click, I access it 128 00:07:50,250 --> 00:07:50,880 right here. 129 00:07:52,000 --> 00:07:59,530 And then when this event gets fired, I do on server event, I could connect a function to it and I 130 00:07:59,530 --> 00:08:02,050 could get the player that fired the event. 131 00:08:02,850 --> 00:08:08,130 I'm going to go back to my local script and I'm going to create the same variable to the event. 132 00:08:09,030 --> 00:08:11,880 So do script dot parent. 133 00:08:13,060 --> 00:08:19,630 And script parent refers to the tool and then I'll get the server script that is a child of the tool, 134 00:08:19,630 --> 00:08:22,960 and then I'll get the clicked event, which is a child of the script. 135 00:08:23,530 --> 00:08:28,900 And now instead, whenever I activate the tool, I'm not going to heal myself, but instead I'm going 136 00:08:28,900 --> 00:08:32,350 to fire this event using the fire server function. 137 00:08:32,350 --> 00:08:33,160 This function. 138 00:08:33,160 --> 00:08:37,600 I'm telling this event that I want to fire information to the server. 139 00:08:37,600 --> 00:08:39,100 I want to fire this event. 140 00:08:39,780 --> 00:08:47,280 So what happens now is that when this event gets fired, this on server event gets fired, gets activated. 141 00:08:47,610 --> 00:08:49,040 This function executes. 142 00:08:49,050 --> 00:08:56,040 So now I can do player, dot, character, dot humanoid and then get its health. 143 00:08:57,710 --> 00:09:00,320 And set it equal to an extra five health. 144 00:09:00,860 --> 00:09:05,030 Now, if I run my game again, we should be able to properly heal. 145 00:09:09,540 --> 00:09:10,860 So I'll damage myself. 146 00:09:11,040 --> 00:09:13,070 And then there we go. 147 00:09:13,080 --> 00:09:15,900 We aren't having that weird thing we saw earlier. 148 00:09:16,470 --> 00:09:18,450 We're actually healing the character now. 149 00:09:24,250 --> 00:09:31,060 Now, there is one slight problem with this system is that an exploiter can actually sit there and fire 150 00:09:31,060 --> 00:09:36,580 this event super fast, making them heal much faster than we would anticipate them to heal. 151 00:09:37,030 --> 00:09:42,100 So a way around this that we could solve is that in our script and our server script that heals our 152 00:09:42,100 --> 00:09:50,830 player, we can create a variable like last clicked and set it to the result of the function tick. 153 00:09:51,690 --> 00:09:58,320 And what this function does is return the current amount of time in seconds, and then when the player 154 00:09:58,320 --> 00:10:05,370 clicks, when they fire this event, we'll check if the current tick minus when they last clicked, 155 00:10:05,370 --> 00:10:14,730 which will give us the difference in seconds and we'll see if this is greater than or equal to maybe 156 00:10:14,730 --> 00:10:19,200 we want to have like a two second limit and then I'll put it into an if statement. 157 00:10:24,540 --> 00:10:31,050 So that means if the last time they clicked was 2 seconds or greater ago, then we'll heal the player. 158 00:10:31,050 --> 00:10:34,470 So this will stop them from being able to spam Click Healing. 159 00:10:36,120 --> 00:10:37,770 So if I run my game again. 160 00:10:40,470 --> 00:10:42,480 And I go and damage my player a little bit. 161 00:10:45,330 --> 00:10:47,310 And then I try to eat this super fast. 162 00:10:47,850 --> 00:10:48,750 It still works. 163 00:10:48,750 --> 00:10:49,710 Why does it still work? 164 00:10:55,840 --> 00:10:58,200 Oh, forgot one simple thing. 165 00:10:58,210 --> 00:10:59,710 We have to of course. 166 00:10:59,710 --> 00:11:02,170 Update last click to tick. 167 00:11:02,170 --> 00:11:02,890 Right. 168 00:11:03,980 --> 00:11:07,850 Otherwise, if we keep it at the same tick, it'll always be greater than two. 169 00:11:07,850 --> 00:11:10,940 Because the last time we clicked was whenever the script ran. 170 00:11:11,090 --> 00:11:14,330 But if we update it again, then we shouldn't be able to spam click it. 171 00:11:15,470 --> 00:11:15,980 Boom. 172 00:11:16,010 --> 00:11:17,870 Another logical error we just fixed. 173 00:11:17,900 --> 00:11:18,740 Easy peasy. 174 00:11:19,430 --> 00:11:21,050 So I may damage myself again. 175 00:11:22,610 --> 00:11:23,600 Grab my donut. 176 00:11:24,550 --> 00:11:31,990 And then now if I spam click, you see, I'm only being I'm only being healed every 2 seconds. 177 00:11:33,080 --> 00:11:36,170 So this is how you add cooldowns to your scripts. 178 00:11:37,420 --> 00:11:42,880 And you can do the same by adding cool downs to your local script, by creating a variable called D 179 00:11:42,880 --> 00:11:43,570 Bounce. 180 00:11:43,870 --> 00:11:46,690 And it's kind of a special word for cooldown. 181 00:11:46,720 --> 00:11:54,160 So by default, we'll set it to false and we'll check if there is a D bounce. 182 00:11:55,030 --> 00:11:57,820 So basically the cooldown still happening. 183 00:11:58,120 --> 00:12:00,190 Then we'll just exit out of the function. 184 00:12:01,180 --> 00:12:03,910 And then we'll make sure to set d bounce to true. 185 00:12:03,940 --> 00:12:06,880 So that way, if it wasn't true, we set it to true. 186 00:12:06,880 --> 00:12:11,800 And then we fire the event and then we can yield for like 2 seconds. 187 00:12:12,910 --> 00:12:15,430 And then we can set d bounce back to false. 188 00:12:15,850 --> 00:12:21,670 Now, this is just a precaution on the client side, and Exploiter could still easily bypass this. 189 00:12:21,670 --> 00:12:28,060 And just Rapidfire the event, which is why we have this sanity check here on the server to make sure 190 00:12:28,060 --> 00:12:30,160 that they aren't rapid firing the event. 191 00:12:30,790 --> 00:12:35,590 We do it here on the client just in case they can't fire this activated event too often. 192 00:12:35,590 --> 00:12:41,050 Like maybe if our activated event had an animation in it that animated them eating the donut, we don't 193 00:12:41,050 --> 00:12:46,030 want them to spam click and have that animation run over and over again and look all glitchy. 194 00:12:46,940 --> 00:12:51,080 And we'll actually get to make animations for our donut in the next lecture. 195 00:12:51,110 --> 00:12:52,160 I'll see you there.